package com.eastseeway.radioproject.utils;

import com.eastseeway.radioproject.base.Const;
import com.eastseeway.radioproject.entities.BaseTCPBean;
import com.eastseeway.radioproject.entities.Bean1FromHandle;
import com.eastseeway.radioproject.entities.BeanOfCalibration;
import com.eastseeway.radioproject.entities.BeanToBottomBoard;
import com.eastseeway.radioproject.entities.BeanToEnergyBoard;
import com.eastseeway.radioproject.entities.BeanToNegativePressureBoard;
import com.eastseeway.radioproject.entities.BeanToSwitchBoard;
import com.eastseeway.radioproject.entities.BeanUpdateFirmware;
import com.eastseeway.radioproject.entities.BottomBoardFunctionCode;
import com.eastseeway.radioproject.entities.FirmwareUpdateCommand;

import java.nio.ByteOrder;

import struct.JavaStruct;
import struct.StructException;

public class CommandGenerator {

    /*
     *生成发送给负压板的命令
     */
    public static byte[] command2NegativePressureBoard(int address, int handleGasPress, int gasContainerPressMin, int gasContainerPressMax, int gasPipeAndHandleDiff)
            throws StructException {
        BeanToNegativePressureBoard beanToNegativePressureBoard = new BeanToNegativePressureBoard();
        beanToNegativePressureBoard.setHandleGasPress(handleGasPress);
        beanToNegativePressureBoard.setGasContainerPressMin(gasContainerPressMin);
        beanToNegativePressureBoard.setGasContainerPressMax(gasContainerPressMax);
        beanToNegativePressureBoard.setGasPipeAndHandleDiff(gasPipeAndHandleDiff);

        return StructTransUtil.pack(address, beanToNegativePressureBoard);
    }

    /**
     * 生成发送给底板的命令
     *
     * @param address
     * @param functionCode  见{@link BottomBoardFunctionCode}
     * @param functionValue
     * @return
     * @throws StructException
     */
    public static byte[] command2BottomBoard(int address, BottomBoardFunctionCode functionCode, short functionValue) throws StructException {
        BeanToBottomBoard beanToBottomBoard = new BeanToBottomBoard();
        beanToBottomBoard.setFunctionCode(functionCode.getCode());
        beanToBottomBoard.setFunctionValue(functionValue);

        return StructTransUtil.pack(address, beanToBottomBoard);
    }

    /*
     *生成发送给手柄1(有负压)的命令
     *负压值发送给手柄时，不用*100，直接发送屏幕的显示值，发送给负压板时，需要*100
    */
    public static byte[] commandData1ToHandle1(int address, byte freq, byte power, byte depth, byte pressure, short continuousDischargePeriod, byte idp, byte idhp, byte idlp, boolean isStart, boolean isIntermittentMode, short shengyucishu) throws StructException {
        Bean1FromHandle bean1FromHandle = new Bean1FromHandle();
        bean1FromHandle.setFreq(freq);
        bean1FromHandle.setPower(power);
        bean1FromHandle.setDepth(depth);
        bean1FromHandle.setPressure(pressure);
        bean1FromHandle.setContinuousDischargePeriod(continuousDischargePeriod);
        bean1FromHandle.setIntermittentDischargePulse(idp);
        bean1FromHandle.setIntermittentDischargeHighLevelPeriod(idhp);
        bean1FromHandle.setIntermittentDischargeLowLevelPeriod(idlp);
        bean1FromHandle.setShengyucishu(shengyucishu);
        byte workState = 0;
        if (isStart) {
            workState |= 0x01;
        }
        if (isIntermittentMode) {
            workState |= 0x02;
        }
        bean1FromHandle.setWorkState(workState);

        return StructTransUtil.pack(address, bean1FromHandle);
    }

    /*
    气压调试：0=正常模式；1=气阀常开
    * */
    public static byte[] commandData1ToHandle1(boolean isNormal) throws StructException {
        Bean1FromHandle bean1FromHandle = new Bean1FromHandle();
        if (isNormal) {
            bean1FromHandle.setWorkState((byte) 0x00);
        } else {
            bean1FromHandle.setWorkState((byte) 0x80);
        }
        return StructTransUtil.pack(Const.ADDRESS_TO_HANDLE_1_DATA_1, bean1FromHandle);
    }

    /*
     *生成发送给手柄2(无负压)的命令
     */
    public static byte[] commandData1ToHandle2(int address, byte freq, byte power, byte depth, boolean isAutoNeedle, short interval, short continuousDischargePeriod, byte idp, byte idhp, byte idlp, boolean isStart, boolean isIntermittentMode, short shengyucishu) throws StructException {
        Bean1FromHandle bean1FromHandle = new Bean1FromHandle();
        bean1FromHandle.setFreq(freq);
        bean1FromHandle.setPower(power);
        bean1FromHandle.setDepth(depth);
        bean1FromHandle.setContinuousDischargePeriod(continuousDischargePeriod);
        bean1FromHandle.setIntermittentDischargePulse(idp);
        bean1FromHandle.setIntermittentDischargeHighLevelPeriod(idhp);
        bean1FromHandle.setIntermittentDischargeLowLevelPeriod(idlp);
        bean1FromHandle.setShengyucishu(shengyucishu);
        bean1FromHandle.setInterval(interval);

        byte workState = 0;
        if (isStart) {
            workState |= 0x01;
        }
        if (isIntermittentMode) {
            workState |= 0x02;
        }
        if (isAutoNeedle) {
            workState |= 0x04;
        }
        bean1FromHandle.setWorkState(workState);
        return StructTransUtil.pack(address, bean1FromHandle);
    }

    /*
     *生成校准命令发送到手柄1和2
     * */
    public static byte[] commandCalibrationDataToHandle(int address, boolean isCalibration, short power, byte freq) throws StructException {
        BeanOfCalibration beanOfCalibration = new BeanOfCalibration();
        beanOfCalibration.setControl(isCalibration ? (byte) 1 : (byte) 0);
        beanOfCalibration.setPower(power);
        beanOfCalibration.setFreq(freq);
        return StructTransUtil.pack(address, beanOfCalibration);
    }

    //    生成发送到手柄的命令3 替换电极命令
    public static byte[] commandReplaceElectrode(int address) throws StructException {
        Bean1FromHandle bean1FromHandle = new Bean1FromHandle();
        bean1FromHandle.setReplaceElectrode((byte) 1);

        return StructTransUtil.pack(address, bean1FromHandle);
    }

    public static byte[] commandToEraseException(int address) throws StructException {
        Bean1FromHandle bean1FromHandle = new Bean1FromHandle();
        bean1FromHandle.setException((byte) 0x80);
        return StructTransUtil.pack(address, bean1FromHandle);
    }

    //    生成发送到手柄的电极信息命令
    public static byte[] commandElectrodeDataToHandle(int address, byte[] electrode_count, byte[] batch_production, byte[] production_number,short shengyucishu) throws StructException {
        Bean1FromHandle bean1FromHandle = new Bean1FromHandle();
        bean1FromHandle.setElectrode_count(electrode_count);
        bean1FromHandle.setBatch_production(batch_production);
        bean1FromHandle.setProduction_number(production_number);
        bean1FromHandle.setShengyucishu_set(shengyucishu);
        return StructTransUtil.pack(address, bean1FromHandle);
    }

//    生成发送到手柄的命令 启动采样上传 关闭阻抗校正
    public static byte[] commandStartSampleUpload(int address, boolean is_start_sample_upload) throws StructException {
        Bean1FromHandle bean1FromHandle = new Bean1FromHandle();
        if (is_start_sample_upload) {
            bean1FromHandle.setTotalPower((short) 0xFFFF);
        }else {
            bean1FromHandle.setSkinResistance((short) 0xFFFF);
        }
        return StructTransUtil.pack(address, bean1FromHandle);
    }

    //    生成发送到能量板的命令
    public static byte[] commandToEnergyBoard(int address, byte freq, boolean is_intermittent, boolean is_standby_state, int idp) throws StructException {
        return commandToEnergyBoard(address, freq, is_intermittent, is_standby_state, false, idp, (byte) 10);
    }

    //    生成发送到能量板的命令
    public static byte[] commandToEnergyBoard(int address, byte freq, boolean is_intermittent, boolean is_standby_state, boolean isCalibration,  int idp, byte continuous_duration) throws StructException {
        BeanToEnergyBoard beanToEnergyBoard = new BeanToEnergyBoard();
        beanToEnergyBoard.setBoardcommand(freq, is_intermittent, is_standby_state, isCalibration);
        beanToEnergyBoard.setCnt_pusle((byte) idp);
        if (isCalibration) {
            beanToEnergyBoard.setContinuous_duration(continuous_duration);
        }
        return StructTransUtil.pack(address, beanToEnergyBoard);
    }

    /*
     * 生成发送到手柄切换板的命令
     * */
    public static byte[] commandToSwitchBoard(int address, byte relay_U_Ctrl, byte relay_V_Ctrl, byte relay_W_Ctrl) throws StructException {
        BeanToSwitchBoard beanToSwitchBoard = new BeanToSwitchBoard(relay_U_Ctrl, relay_V_Ctrl, relay_W_Ctrl);
        return StructTransUtil.pack(address, beanToSwitchBoard);
    }

    /*
     *生成发送固件更新的命令
     */
    public static byte[] commandUpdateFirmware(int address, FirmwareUpdateCommand cmd_title, int cmd_content) throws StructException {
        BeanUpdateFirmware beanUpdateFirmware = new BeanUpdateFirmware();
        beanUpdateFirmware.setCmd_title(cmd_title.getValue());
        beanUpdateFirmware.setCmd_content(cmd_content);

        BaseTCPBean baseTCPBean = new BaseTCPBean();
        baseTCPBean.setAddress(address);
        baseTCPBean.setContent(JavaStruct.pack(beanUpdateFirmware, ByteOrder.LITTLE_ENDIAN));

        return JavaStruct.pack(baseTCPBean, ByteOrder.LITTLE_ENDIAN);

    }

    //    更新数据库时使用id，因此id需要受控，不能使用自增
    public static String generateId(int userId, boolean hasPressure, int position) {
        return userId + (hasPressure ? "1" : "0") + position;
    }

//    生成请求固件信息的命令 只有切换板 负压板用这个命令，底板用原来的命令
    public static byte[] commandRequestVersionInfo(int address) throws StructException {
        BaseTCPBean baseTCPBean = new BaseTCPBean();
        baseTCPBean.setAddress(address);
        baseTCPBean.setContent(new byte[64]);
        return JavaStruct.pack(baseTCPBean, ByteOrder.LITTLE_ENDIAN);
    }
}
